package com.ruoyi.quartz.task;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.Web3Utils;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.domain.WdyEthTxn;
import com.ruoyi.system.domain.WdyUser;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.IWdyEthTxnService;
import com.ruoyi.system.service.IWdyUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 查找以太坊充值记录
 */
@Component("ethTask")
public class EthTask {

    private static final Logger logger = LoggerFactory.getLogger(EthTask.class);

    public static final String BLOCK_HEIGHT = "block_height";
    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private IWdyUserService userService;

    @Autowired
    private IWdyEthTxnService wdyEthTxnService;

    @Value("${wallet.ethurl}")
    private String url;

    @Value("${wallet.contract.usdt}")
    private String usdtContract;


    @PostConstruct
    public void init() {
        try {
            Web3Utils.setUrl(url);
            //TODO 获取所有合约地址列表，状态为0的合约地址列表
            List<String> sList = new ArrayList<>();
            sList.add(usdtContract);
            Web3Utils.setContractAddrList(sList);
            Web3Utils.init();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void filterTxn() throws Exception {
        QueryWrapper<WdyUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("user_id", "wallet_address");
        List<WdyUser> list = userService.list(queryWrapper);
        for(WdyUser u : list) {
            if(StringUtils.isNotEmpty(u.getWalletAddress())) {
                Web3Utils.putAddrMap(u.getWalletAddress(), u.getUserId());
            }
        }
        //TODO 获取数据库的区块高度，如11
        long dbBlockHeight = Long.parseLong(sysConfigService.selectConfigByKey(BLOCK_HEIGHT));
        Web3Utils.Res res = new Web3Utils.Res();
        res.beginBlock = new BigInteger(dbBlockHeight + "");
        Web3Utils.confirmEndBlock(res);

        //TODO 更新状态为0的用户地址列表，更新状态到1，防止新生成的充值地址未被加入
        res = Web3Utils.getChargeInfos(res);
        if (res == null || res.ents == null) {
            return;
        }
        if (res != null && !res.ents.isEmpty()) {
            //System.out.println(res);
            Map<String, String> addrMap = Web3Utils.getAddrmap();
            for (Web3Utils.Ent ent : res.ents) {

                //TODO 根据合约地址和充值地址获取用户余额信息

                //TODO 验证查询事务是否存在，防止重复事务

                //TODO 用合约地址判断是否是以太或者代币充值
                //精度转换 代币
                //		以太 ent.getVal().divide(new BigDecimal("1"), 8, BigDecimal.ROUND_DOWN).doubleValue()
                //TODO 金额太小可不做处理
                QueryWrapper<WdyEthTxn> query = new QueryWrapper<>();
                query.eq("txn_hash", ent.getTxHash());
                if(wdyEthTxnService.count(query) == 0) {
                    BigDecimal value = BigDecimal.ZERO;
                    WdyEthTxn wdyEthTxn = new WdyEthTxn();
                    if(Web3Utils.ETH_FLAG.equals(ent.getContractAddress())) {
                        value = ent.getVal().setScale(10, BigDecimal.ROUND_DOWN);;
                        wdyEthTxn.setTxnCurrency(WdyEthTxn.ETH);
                    } else if(usdtContract.equals(ent.getContractAddress())) {
                        value = ent.getVal().divide(new BigDecimal(1000000), 6, BigDecimal.ROUND_DOWN);
                        wdyEthTxn.setTxnCurrency(WdyEthTxn.USDT);
                    }
                    if(value.compareTo(BigDecimal.ZERO) > 0) {
                        wdyEthTxn.setTxnValue(value);
                        wdyEthTxn.setUserId(addrMap.get(ent.getTo()));
                        wdyEthTxn.setTxnHash(ent.getTxHash());
                        wdyEthTxnService.save(wdyEthTxn);
                    }
                }
            }
        }

        //TODO 更新最新处理的块高度 res.endBlock - 1
        SysConfig updateConfig = new SysConfig();
        updateConfig.setConfigValue(String.valueOf(res.endBlock.longValue() - 1));
        QueryWrapper<SysConfig> updateWrapper = new QueryWrapper<>();
        updateWrapper.eq("config_key", BLOCK_HEIGHT);
        sysConfigService.update(updateConfig, updateWrapper);
    }

    public void handleTxn() {
        QueryWrapper<WdyEthTxn> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("txn_state", WdyEthTxn.PROCESSING);
        List<WdyEthTxn> list = wdyEthTxnService.list(queryWrapper);
        if(CollectionUtils.isEmpty(list)) {
            return;
        }
        list.forEach(t -> {
            try {
                wdyEthTxnService.handleTxn(t);
            } catch (Exception e) {
                logger.error("处理交易异常", e);
            }
        });
    }
}
